package MeteoCal.bean;

import MeteoCal.manager.EventManager;
import MeteoCal.manager.InvitationManager;
import MeteoCal.utility.Mail;
import MeteoCal.manager.NotificationManager;
import MeteoCal.manager.UserManager;
import MeteoCal.entity.Event;
import MeteoCal.entity.Invitation;
import MeteoCal.entity.InvitationPK;
import MeteoCal.entity.Notification;
import MeteoCal.entity.Receivednotification;
import MeteoCal.entity.ReceivednotificationPK;
import MeteoCal.entity.User;
import MeteoCal.entity.Weatherforecast;
import MeteoCal.manager.WeatherManager;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import javax.ejb.EJB;
import javax.enterprise.context.ConversationScoped;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;

/**
 *
 * @authors Guttadoro, Iommazzo, Saullo
 */

@ManagedBean(name="eventBean")
@SessionScoped
public class EventBean implements Serializable{

    @EJB
    EventManager em;
    @EJB
    UserManager um;
    @EJB
    InvitationManager im;
    @EJB
    NotificationManager nm;
    @EJB
    WeatherManager wm;
    
    List<User> users;
    List<User> participants;
    List<User> participantstomodify;
    
    String par = new String();
    
    Boolean create = true;
    Boolean update = true;
    Boolean retrieve = true;

    Event eventOld;
    
    public Boolean getRetrieve() {
        return retrieve;
    }

    public void setRetrieve(Boolean retrieve) {
        this.retrieve = retrieve;
    }

    public Boolean getCreate() {
        return create;
    }

    public void setCreate(Boolean create) {
        this.create = create;
    }

    public Boolean getUpdate() {
        return update;
    }

    public void setUpdate(Boolean update) {
        this.update = update;
    }

    public String getPar() {
        return par;
    }

    public void setPar(String par) {
        this.par = par;
    }

    public List<User> getParticipantstomodify() {
        return participantstomodify;
    }

    public void setParticipantstomodify(List<User> participantstomodify) {
        this.participantstomodify = participantstomodify;
    }
    
    private Event e;


    public List<User> getParticipants() {
        return participants;
    }

    public void setParticipants(List<User> participants) {
        this.participants = participants;
    }
    
    public Event getE() {
        
        return e;
    }

    public void setE(Event e) {
        this.e = e;
    }
    
    public EventBean() {
        
    }
      
    public String getEventDB(Event event) {
        
        
        if (event == null)
            retrieve = false;
        else {
            retrieve = true;
            String emailc = event.getIdCreator().getEmail();
            String emailu = um.getLoggedUser().getEmail();

            if(event.getPublic1() || emailc.equals(emailu) || event.getUsers().contains(emailu)){
                e = event;
                par = "ok";
            }
            else par = "err";
        }
        
        return "event?faces-redirect=true";
    }
    
    public String getEventDB(int id) {
        
        Event event = em.getEvent(id); //cattura eccezioni
        if (event == null)
            retrieve = false;
        else {
            retrieve = true;
            String emailc = event.getIdCreator().getEmail();
            String emailu = um.getLoggedUser().getEmail();

            if(event.getPublic1() || emailc.equals(emailu) || event.getUsers().contains(emailu)){
                e = event;
                par = "ok";
            }
            else par = "err";
        }
        
        return "event?faces-redirect=true";
    }
    
    
    public ArrayList<Event> getEventsList(String name, String city){
        return em.getEventsList(name, city); //cattura eccezioni
    }
    
    public String getName() {
        return e.getName();
    }

    public void setName(String name) {
        e.setName(name);
    }

    public String getAddress() {
        return e.getAddress();
    }

    public void setAddress(String address) {
        e.setAddress(address);
    }

    public String getCity() {
        return e.getCity();
    }

    public void setCity(String city) {
       e.setCity(city);
    }

    public Date getDateBegin() {
        return e.getDateBegin();
    }

    public void setDateBegin(Date dateBegin) {
        e.setDateBegin(dateBegin);
    }

    public Date getDateEnd() {
        return e.getDateEnd();
    }

    public void setDateEnd(Date dateEnd) {
        e.setDateEnd(dateEnd);
    }

    public Date getHourBegin() {
        return e.getHourBegin();
    }

    public void setHourBegin(Date hourBegin) {
        e.setHourBegin(hourBegin);
    }

    public Date getHourEnd() {
        return e.getHourEnd();
    }

    public void setHourEnd(Date hourEnd) {
        e.setHourEnd(hourEnd);
    }

    public String getDescription() {
        return e.getDescription();
    }

    public void setDescription(String description) {
        e.setDescription(description);
    }

    public Boolean getOutdoor() {
        return e.getOutdoor();
    }

    public void setOutdoor(Boolean outdoor) {
        e.setOutdoor(outdoor);
    }

    public Boolean getPublic1() {
        return e.getPublic1();
    }

    public void setPublic1(Boolean public1) {
        e.setPublic1(public1);
    }
    
    public Collection<Invitation> getInvitation() {
        return e.getInvitationCollection();
    }

    public void setInvitation(Collection<Invitation> invitation) {
        e.setInvitationCollection(invitation);
    }
    
    private Boolean sameDateStartEnd (){ 
        return (e.getDateBegin().equals(e.getDateEnd()) && e.getHourBegin().after(e.getHourEnd()));
         
    }
    
    private Boolean afterNow(){ 
        Date today = new Date();
        Date date = e.getDateBegin();
        date.setHours(e.getHourBegin().getHours());
        date.setMinutes(e.getHourBegin().getMinutes());
        return (date.before(today));
           
            
    }
    
    public List<User> getParticipant(){

        
        Collection<Invitation> invitation = im.getInvitation(e);
        //List<User> u = new ArrayList<>();
        
        participants = new ArrayList<>();
        participantstomodify = new ArrayList<>();
        
        for (Invitation i: invitation){
            if(i.getResponse().equals("Yes"))
                participants.add(i.getUser());
            else participantstomodify.add(i.getUser());
        }
        /*if(u.isEmpty()){
            User temp = new User();
            temp.setEmail("");
            temp.setSurname("");
            temp.setName("");
            u.add(temp);
        }*/
        
        //participants = u;
        //participantstomodify.addAll(u);
        
        return participants;
       
    }
    
    public String tocreateEvent (){
        e = new Event();
        this.participantstomodify = new ArrayList();
        this.participants = new ArrayList();
        users = um.getUsers();
        users.remove(um.getLoggedUser());
        par = "false";
        return "cuEvent?faces-redirect=true";
    }
    
    public void createEvent(){ 
        
        if(sameDateStartEnd() || afterNow())
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "Warning!", "Please, insert a correct date/hour interval"));
        else {
            Event newevent = e;
            create = em.createEvent(newevent.setHoursInDate(), um.getLoggedUser());
            update = true;
        }
    }
     
    public Date minDate(){
        return Calendar.getInstance().getTime();
    }
    /* ale */
    
    
    public String ClickOnApply() throws Exception{
        
        
                                  
        if(par.equals("true")) 
            updateEvent();
        else createEvent();
        
        if (create && update){
            String namecreator = e.getIdCreator().getName();
            String surncreator = e.getIdCreator().getSurname();
            String objmail = "Event changes, by \""+namecreator+" "+surncreator+"\"";
            if (participantstomodify != null)
                removeDuplicates(participantstomodify);
        
            List<User> temp = new ArrayList<>();

            if (participants != null)            
                temp.addAll(participants);

            if (participantstomodify != null && participants != null){
                participants.removeAll(participantstomodify);
                participantstomodify.removeAll(temp);
                temp.removeAll(participants);
            }

            System.err.println("pARTICIPANTS ---> " + participants + " participantstomodify -->" + this.participantstomodify);
            sendNotificationElPart(participants);
            
            
            
            
        if(update && par.equals("true")){
            //Event ev = em.getEvent(e.getIdEvent());
            eventOld.getDateBegin().setHours(e.getDateBegin().getHours());
            eventOld.getDateBegin().setMinutes(e.getDateBegin().getMinutes());
            eventOld.getDateEnd().setHours(e.getDateEnd().getHours());
            eventOld.getDateEnd().setMinutes(e.getDateEnd().getMinutes());
            System.err.println("Date begin --> " + e.getDateBegin().toString() + " " + eventOld.getDateBegin().toString());
            System.err.println("Date end --> " + e.getDateEnd().toString() + " " + eventOld.getDateEnd().toString());
            System.err.println("hour begin --> " + e.getHourBegin().toString() + " " + eventOld.getHourBegin().toString());
            System.err.println("hour end --> " + e.getHourEnd().toString() + " " + eventOld.getHourEnd().toString());
            
            
            if (!e.getDateBegin().equals(eventOld.getDateBegin()) || 
                !e.getDateEnd().equals(eventOld.getDateEnd()) ||
                !e.getHourBegin().equals(eventOld.getHourBegin())||
                !e.getHourEnd().equals(eventOld.getHourEnd())){
                for (User u: temp){
                    System.err.println("Tempo diverso ------------------");
                    im.changeResponseMaybe(u,e);
                    
                    String textmail = "Hi "+u.getName()+",<br><br>"+
                                  namecreator+" "+surncreator+" has changed the dates or the hours from <b>\""+
                                  e.getName()+"\"</b><br><br>"+"So, your participation has modified into the state \"Maybe\"."
                                  +" Login into MeteoCal and re-reply to it."+
                                  "<br>Many thanks,<br><i>MeteoCal Staff</i><br><br><br><font size=\"1\" color=\"gray\">"+
                                  "This mail has been sent automatically, so please do not reply to this address</font>";

                    Mail.sendMail(u.getEmail(), e.getIdCreator().getEmail(), objmail, textmail);
                }
                
                
            }
            else if (!e.getCity().equals(eventOld.getCity()) ||
                     e.getOutdoor() != eventOld.getOutdoor()){
                
                for (User u: temp){
                    
                    String textmail = "Hi "+u.getName()+",<br><br>"+
                                  namecreator+" "+surncreator+" has changed some information about <b>\""+
                                  e.getName()+"\"</b><br><br>"+"Login into MeteoCal and see it."+
                                  "<br>Many thanks,<br><i>MeteoCal Staff</i><br><br><br><font size=\"1\" color=\"gray\">"+
                                  "This mail has been sent automatically, so please do not reply to this address</font>";

                    Mail.sendMail(u.getEmail(), e.getIdCreator().getEmail(), objmail, textmail);
                }
            }
                
        }
            
        sendInvitation(participantstomodify);
        }
        if(!update) 
            e = em.getEvent(e.getIdEvent());
        
        if(!create)
            return "cuEvent?faces-redirect=true";
        
        return "event?faces-redirect=true";
        
    }
    
    public void removeDuplicates(List<User> lista){
    for (int i = 0 ; i < lista.size() ; i++){
        String currObj= lista.get(i).getEmail();
        for (int k=i+1 ; k< lista.size() ; k++){
            String tmpObj=(String) lista.get(k).getEmail();
            if (currObj.equals(tmpObj)){
              lista.remove(k);
                      k--;
                    }
        }
    }
}
    public void sendNotificationElPart(List<User> selected) throws NullPointerException{
        
        if (selected != null) {
            String namecreator = e.getIdCreator().getName();
            String surncreator = e.getIdCreator().getSurname();
            String objmail = "Participant Elimination, by \""+namecreator+" "+surncreator+"\"";

            Date d = new Date();

            Notification n = new Notification();
            n.setDate(d);
            n.setIdEvent(e);
            n.setText("delete participant");

            nm.saveNotElPart(n);
            
            Collection<Receivednotification> listrn = new ArrayList<>();
            
            Receivednotification rn = new Receivednotification();
            rn.setNotification(n);
            rn.setReadn(false);
            
            ReceivednotificationPK rnPK = new ReceivednotificationPK();
            rnPK.setIdNotification(n.getIdNotification());
            
            im.removeInvitations(selected, e);

            for (User u : selected){
                
                rnPK.setIdUser(u.getEmail());
                rn.setReceivednotificationPK(rnPK);
                rn.setUser(u);
                
                listrn.add(rn);
                
                String textmail = "Hi "+u.getName()+",<br><br>"+
                                  namecreator+" "+surncreator+" has deleted you as participant from <b>\""+
                                  e.getName()+"\"</b> :(<br><br>"+"We are so sorry. However, we hope to see you soon in our application.<br>"+
                                  "<br>Many thanks,<br><i>MeteoCal Staff</i><br><br><br><font size=\"1\" color=\"gray\">"+
                                  "This mail has been sent automatically, so please do not reply to this address</font>";

                Mail.sendMail(u.getEmail(), e.getIdCreator().getEmail(), objmail, textmail);

            }
            
            n.setReceivednotificationCollection(listrn);
            nm.upadateNotification(n);
            
                        
        }
    }
    
    public void sendInvitation(List<User> selected){
        
        if (selected != null) {
            String namecreator = e.getIdCreator().getName();
            String surncreator = e.getIdCreator().getSurname();
            String objmail = "New Invite by \""+namecreator+" "+surncreator+"\"";

            Date d = new Date();

            Invitation i = new Invitation();
            i.setDateTimeRequest(d);
            i.setEvent(e);
            i.setResponse("Maybe");

            InvitationPK ipk = new InvitationPK();
            ipk.setIdEvent(e.getIdEvent());

            for (User u : selected){

                ipk.setIdUser(u.getEmail());
                i.setInvitationPK(ipk);
                i.setUser(u);
                im.addInvitation(i);
                getInvitation().add(i);
                setInvitation(getInvitation());
                String textmail = "Hi "+u.getName()+",<br><br>"+
                                  namecreator+" "+surncreator+" has invited you to participate at <b>\""+
                                  e.getName()+"\"</b><br><br>"+"Login into MeteoCal and reply to it. Simple, isn't it?<br>"+
                                  "<br>See you soon,<br><i>MeteoCal Staff</i><br><br><br><font size=\"1\" color=\"gray\">"+
                                  "This mail has been sent automatically, so please do not reply to this address</font>";

                Mail.sendMail(u.getEmail(), e.getIdCreator().getEmail(), objmail, textmail);

            }
        }
    }
    
    public void updateEvent(){
        this.eventOld = new Event(em.getEvent(e.getIdEvent()));
        update = em.updateEvent(um.getLoggedUser(),e);
        if(wm.findWeatherByCityAndDate(e.getCity(), e.getDateBegin()).isEmpty())
                wm.createWeather(e);
        create = true;
    }
            
            
    public String ClickOnUpdate() {
        //em.setEvent(e);
        users = um.getUsers();
        users.remove(um.getLoggedUser());
        users.removeAll(participantstomodify);
        
        
        participantstomodify.clear();
        participantstomodify.addAll(participants);
        
        par = "true";

        return "cuEvent?faces-redirect=true&u=true";
    } 
    
    public List<User> getUsers(){
        return users;
    }
    
    public boolean isCreator (){
        
        return e.getIdCreator().equals(um.getLoggedUser());
        
    }
    
    public String ClickOnDelete() {
        
        String namecreator = e.getIdCreator().getName();
        String surncreator = e.getIdCreator().getSurname();
        String objmail = "Elimination event by \""+namecreator+" "+surncreator+"\"";
        
        participantstomodify.addAll(getParticipant());
        
        for (User u: participantstomodify){
            String textmail = "Hi "+u.getName()+",<br><br>"+
                                  namecreator+" "+surncreator+" has deleted this event <b>\""+
                                  e.getName()+"\"</b><br><br>"+"Therefore, your participantion, for that event, is no longer required.<br>"+
                                  "<br>See you soon,<br><i>MeteoCal Staff</i><br><br><br><font size=\"1\" color=\"gray\">"+
                                  "This mail has been sent automatically, so please do not reply to this address</font>";

            Mail.sendMail(u.getEmail(), e.getIdCreator().getEmail(), objmail, textmail);
        }
        
        em.removeEvent(e);
        e = new Event();
        
        return "homepage?faces-redirect=true";
    }
    
    public void msgInfo(){
        if(par.equals("err"))
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Info", "You are not allowed to view the event."));
        if(!update)
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "Attention!", "Impossible to update event due to overlapping with other existing event"));
        if(!create)
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "Attention!", "Impossible to create event due to overlapping with other existing event"));
        if(!retrieve)
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "Warning!", "Ops! This is embarrassing. The event searched is no longer available"));

    }
    
    public String weatherRetrieve(){
         
            List<Weatherforecast> weatherforecast = wm.findWeatherByCityAndDate(e.getCity(),e.getDateBegin());
            if (weatherforecast.isEmpty())
                return "http://www.cheesium.com/idlist/index_files/unknown_icon32.png";        
            return "http://openweathermap.org/img/w/"+weatherforecast.get(0).getResult_icon()+".png";

        
    }
    
    public String weatherDescriprionRetrieve(){
         
        List<Weatherforecast> weatherforecast = wm.findWeatherByCityAndDate(e.getCity(),e.getDateBegin());
        if (weatherforecast.isEmpty())
                    return "Unknown weather forecasts";

            return weatherforecast.get(0).getResult_description();
        
    }
}
